﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
using DeSleeper.Library;

namespace DeSleeper.Client.Framework
{
    [Export(typeof(ICommandMessageProvider))]
    class DefaultMessageProvider : ICommandMessageProvider
    {
        public DefaultMessageProvider()
        {
            _unacknowledgedMessages = new ObservableCollection<CommandMessage>();
            _unacknowledged = new ReadOnlyObservableCollection<CommandMessage>(_unacknowledgedMessages);
        }

        #region ICommandMessageProvider Implementation
        private readonly ObservableCollection<CommandMessage> _unacknowledgedMessages;
        private readonly ReadOnlyObservableCollection<CommandMessage> _unacknowledged;
        public ReadOnlyObservableCollection<CommandMessage> Unacknowledged
        {
            get { return _unacknowledged; }
        }

        public void Acknowledge(CommandMessage message)
        {
            _unacknowledgedMessages.Remove(message);
        }

        public void AddMessage(CommandMessage message)
        {
            _unacknowledgedMessages.Insert(0, message);
        }

        public void AddStartMessage(AsyncCommand command)
        {
            AddMessage(new CommandMessage(command, CommandMessageType.Progress, command.StartingMessage));
        }

        public void AddCompleteMessage(AsyncCommand command)
        {
            var expiredItems = _unacknowledged.Where(
                item => item.AssociatedCommand == command && item.MessageType == CommandMessageType.Progress).ToList();
            foreach (var commandMessage in expiredItems)
                _unacknowledgedMessages.Remove(commandMessage);

            AddMessage(new CommandMessage(command, CommandMessageType.Success, command.CompletedMessage));
        }

        public void AddError(AsyncCommand command, Exception ex)
        {
            if (ex is AggregateException)
                ex = new SelfFlatteningException(string.Empty, ex);
            AddMessage(new CommandMessage(command, CommandMessageType.Error, ex.Message));
        }

        #endregion
    }
}
